package mk.jug.academy.service;

import java.util.List;

import mk.jug.academy.model.Course;
import mk.jug.academy.model.Lecturer;
import mk.jug.academy.model.Page;
import mk.jug.academy.model.status.LecturerStatus;


/**
 * The contract defining the available services regarding a {@link Lecturer}.
 *
 * @author Ice.Penov
 */
public interface LecturerService {
	
	/**
	 * Registers a new {@link Lecturer} in the academy.
	 */
	void registerLecturer(Lecturer lecturer);
	
	/**
	 * Returns all the {@link Lecturer}s in the system,
	 * in a paged manner.
	 */
	Page<Lecturer> listAll(int pageNumber, int itemsPerPage);
	
	/**
	 * Returns the {@link Lecturer}s in the academy with
	 * the {@link LecturerStatus#SIGNED_UP} status, in a paged manner.
	 */
	Page<Lecturer> listSignedUp(int pageNumner, int itemsPerPage);
	
	/**
	 * Returns the {@link Lecturer}s in the academy with
	 * the {@link LecturerStatus#ACTIVE} status, in a paged manner.
	 */
	Page<Lecturer> listActive(int pageNumber, int itemsPerPage);
	
	/**
	 * Returns the {@link Lecturer}s in the academy with
	 * the {@link LecturerStatus#REJECTED} status, in a paged manner.
	 */
	Page<Lecturer> listRejected(int pageNumber, int itemsPerPage);
	
	/**
	 * Returns the {@link Lecturer}s by status, sorted by newest date. 
	 */
	Page<Lecturer> listLatestByStatus(int pageNumber, int itemsPerPage, LecturerStatus status);
	
	/**
	 * Returns the {@link Lecturer}s in the academy with
	 * the {@link LecturerStatus#RETIRED} status, in a paged manner.
	 */
	Page<Lecturer> listRetired(int pageNumber, int itemsPerPage);
	
	/**
	 * Accepts a registration of a {@link Lecturer}.
	 * The {@link Lecturer} lands in the {@link LecturerStatus#ACTIVE} state. 
	 */
	void acceptRegistration(Lecturer lecturer);
	
	/**
	 * Rejects a registration of a {@link Lecturer}.
	 * The {@link Lecturer} lands in the {@link LecturerStatus#REJECTED} state. 
	 */	
	void rejectRegistration(Lecturer lecturer);
	
	/**
	 * Retires a {@link Lecturer}.
	 * The {@link Lecturer} lands in the {@link LecturerStatus#RETIRED} state. 
	 */		
	void retireLecturer(Lecturer lecturer);
	
	/**
	 * Gets the {@link Course}s for the given {@link Lecturer}.
	 */
	List<Course> fetchCoursesForLecturer(Lecturer lecturer);

	/**
	 * Gets the course for its ID.
	 */
	Lecturer load(Long id);
	
	/**
	 * Saves the changed properties.
	 */
	void saveChanges(Lecturer lecturer);
	
	/**
	 * Checks whether the {@link Lecturer} with the specified email exists.
	 */
	boolean exists(String email);
	
	/**
	 * Returns the {@link Lecturer} with the given email.
	 */
	Lecturer findByEmail(String email);

	/**
	 * Fetches the {@link Lecturer}s with {@link LecturerStatus#ACTIVE}
	 */
	List<Lecturer> fetchActive();

}